from flask import Blueprint, request, jsonify, render_template
from app.models.inventory import Inventory, StockDoc, StockDocItem
from app.utils.doc_utils import generate_doc_id
from datetime import datetime
from flask_login import login_required
from app.utils.log_config import get_logger
from app.utils.error_handler import error_handler, validate_request
import uuid

# 配置日志
logger = get_logger('inventory')

inventory_bp = Blueprint('inventory', __name__)

# 自有库存页面
@login_required
@error_handler
@inventory_bp.route('/')
def inventory_index():
    try:
        # 使用ORM模型获取所有库存数据
        inventory_items = Inventory.find_all()
        # 转换为字典列表
        inventory_list = [item.to_dict() for item in inventory_items]
        
        return render_template('index.html', inventory_data=inventory_list)
    except Exception as e:
        logger.error(f'获取库存数据失败: {e}')
        return render_template('index.html', inventory_data=[], error='获取库存数据失败')

@login_required
@error_handler
@inventory_bp.route('/api/inventory')
def get_paginated_inventory():
    try:
        # 获取分页参数
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 20, type=int)
        order_by = request.args.get('order_by', 'id')
        
        # 使用分页查询
        pagination = Inventory.paginate(
            page=page, 
            per_page=per_page, 
            order_by=order_by
        )
        
        # 转换为字典格式返回
        return jsonify({
            'items': [item.to_dict() for item in pagination.items],
            'page': pagination.page,
            'per_page': pagination.per_page,
            'total': pagination.total,
            'pages': pagination.pages,
            'has_prev': pagination.has_prev,
            'has_next': pagination.has_next,
            'prev_num': pagination.prev_num,
            'next_num': pagination.next_num
        })
    except Exception as e:
        logger.error(f"获取库存API数据失败: {e}")
        return jsonify({"error": "获取库存数据失败"}), 500

# 获取自有库存（使用已有的api_inventory路由）

# 入库接口（带/api前缀）
@login_required
@error_handler
@validate_request('product_id', 'product_name', 'quantity', 'warehouse')
@inventory_bp.route('/api/inventory/in', methods=['POST'])
def stock_in():
    try:
        data = request.get_json()
        
        # 参数验证
        try:
            quantity = int(data['quantity'])
            if quantity <= 0:
                return jsonify({'status': 'error', 'message': '数量必须为正数'}), 400
        except ValueError:
            return jsonify({'status': 'error', 'message': '数量必须是数字'}), 400

        doc_id = generate_doc_id("入库")
        operator = "admin"
        current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        # 使用事务处理入库操作
        try:
            # 创建出入库单据
            stock_doc = StockDoc(
                doc_id=doc_id,
                doc_type="入库",
                warehouse=data['warehouse'],
                operator=operator,
                create_time=current_time,
                status="已完成"
            )
            if not stock_doc.save():
                raise Exception("创建入库单据失败")
            
            # 创建单据明细
            doc_item = StockDocItem(
                doc_id=doc_id,
                product_id=data['product_id'],
                product_name=data['product_name'],
                quantity=quantity
            )
            if not doc_item.save():
                raise Exception("创建单据明细失败")
            
            # 检查库存是否存在
            existing_inventory = Inventory.find_by_product_id(
                product_id=data['product_id'],
                warehouse=data['warehouse']
            )
            
            if existing_inventory:
                # 更新库存
                if not existing_inventory.update_quantity(quantity):
                    raise Exception("更新库存失败")
            else:
                # 新增库存
                new_inventory = Inventory(
                    product_name=data['product_name'],
                    product_id=data['product_id'],
                    quantity=quantity,
                    warehouse=data['warehouse'],
                    update_time=current_time
                )
                if not new_inventory.save():
                    raise Exception("新增库存失败")
            
            logger.info(f'入库成功: {data["product_name"]} {quantity}')
            return jsonify({'status': 'success', 'message': '入库成功', 'doc_id': doc_id})
        except Exception as e:
            logger.error(f'入库事务失败: {e}')
            return jsonify({'status': 'error', 'message': f'入库失败: {str(e)}'}), 500
    except Exception as e:
        logger.error(f'入库操作失败: {e}')
        return jsonify({'status': 'error', 'message': '入库失败'}), 500

# 出库接口（带/api前缀）
@login_required
@error_handler
@validate_request('product_id', 'quantity', 'warehouse')
@inventory_bp.route('/api/inventory/out', methods=['POST'])
def stock_out():
    try:
        data = request.get_json()
        
        # 参数验证
        try:
            quantity = int(data['quantity'])
            if quantity <= 0:
                return jsonify({'status': 'error', 'message': '数量必须为正数'}), 400
        except ValueError:
            return jsonify({'status': 'error', 'message': '数量必须是数字'}), 400

        # 检查商品是否存在且库存足够
        inventory = Inventory.find_by_product_id(
            product_id=data['product_id'],
            warehouse=data['warehouse']
        )
        
        if not inventory:
            return jsonify({'status': 'error', 'message': '商品在该仓库不存在'}), 404
        
        if inventory.quantity < quantity:
            return jsonify({'status': 'error', 'message': f'库存不足（当前：{inventory.quantity}）'}), 400

        doc_id = generate_doc_id("出库")
        operator = "admin"
        current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        # 使用事务处理出库操作
        try:
            # 创建出库单据
            stock_doc = StockDoc(
                doc_id=doc_id,
                doc_type="出库",
                warehouse=data['warehouse'],
                operator=operator,
                create_time=current_time,
                status="已完成"
            )
            if not stock_doc.save():
                raise Exception("创建出库单据失败")
            
            # 创建单据明细
            doc_item = StockDocItem(
                doc_id=doc_id,
                product_id=data['product_id'],
                product_name=inventory.product_name,
                quantity=quantity
            )
            if not doc_item.save():
                raise Exception("创建单据明细失败")
            
            # 更新库存
            if not inventory.update_quantity(-quantity):
                raise Exception("更新库存失败")
            
            logger.info(f'出库成功: {inventory.product_name} {quantity}')
            return jsonify({'status': 'success', 'message': '出库成功', 'doc_id': doc_id})
        except Exception as e:
            logger.error(f'出库事务失败: {e}')
            return jsonify({'status': 'error', 'message': f'出库失败: {str(e)}'}), 500
    except Exception as e:
        logger.error(f'出库操作失败: {e}')
        return jsonify({'status': 'error', 'message': '出库失败'}), 500